package com.quicks.beauty.server.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qq.weixin.mp.aes.PKCS7Encoder;
import com.quicks.beauty.core.entity.WxUser;
import com.quicks.beauty.server.common.AjaxResult;
import com.quicks.beauty.server.config.WXConfig;
import com.quicks.beauty.server.service.UserService;
import com.quicks.beauty.server.vos.OtherInfoVo;
import com.quicks.beauty.server.vos.WXOpenId;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicHeader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import weixin.popular.bean.wxa.WxaDUserInfo;
import weixin.popular.client.LocalHttpClient;
import weixin.popular.util.JsonUtil;
import weixin.popular.util.WxaUtil;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * TODO 获取用户的OpenID
 */
@Controller
@RequestMapping(value = "mini")
@Api(tags = "获取用户的OpenID")
public class OpenIdController {

    protected static Header jsonHeader = new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
    @Autowired
    private WXConfig wxConfig;

    @Autowired
    @Qualifier(value = "redisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private UserService userService;


    @RequestMapping(value = "getOpenId", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "获取用户的OpenID")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "jsCode", value = "jsCode，", paramType = "query", required = true, dataType = "String")
    })
    public AjaxResult getUserOpenId(@RequestParam("jsCode") String jsCode) {
        HttpUriRequest httpUriRequest = RequestBuilder.post()
                .setHeader(jsonHeader)
                .setUri(wxConfig.getBaseUrl() + wxConfig.getCodeSession())
                .addParameter("appid", wxConfig.getAppId())
                .addParameter("secret", wxConfig.getAppSecret())
                .addParameter("js_code", jsCode)
                .addParameter("grant_type", "authorization_code")
                .build();

        AjaxResult results = null;
        try {
            results = new AjaxResult();
            WXOpenId result = LocalHttpClient.executeJsonResult(httpUriRequest, WXOpenId.class);
            System.out.println(result);
            String openId = result.openId;
            if (openId != null) {
                String tempId = UUID.randomUUID().toString();
                results.setSuccess(true);
                results.setData(openId);
                results.setInfo(result.getSession_key());
                OtherInfoVo info = new OtherInfoVo(tempId, jsCode, result.getSession_key());
                info.setOpenId(openId);
                ValueOperations<String, Object> forValue = redisTemplate.opsForValue();
                forValue.set(tempId,info,2, TimeUnit.HOURS);
            } else {
                results.setSuccess(false);
                results.setData("服务器请求出错,请检查jsCode");
            }
        } catch (Exception e) {
            results.setSuccess(false);
            results.setMsg("系统打盹,请稍后...");
            e.printStackTrace();
        }

        return results;

    }


    @ResponseBody
    @RequestMapping(value = "getOther")
    public AjaxResult getUserOtherPhone(String tempId, String encryptedData, String iv){
        AjaxResult result = new AjaxResult();
        try {

            if(null==encryptedData|| "undefined".equals(encryptedData)){
                result.setMsg("参数不合法");
                result.setSuccess(false);
                return result;
            }

            if(null==iv|| "undefined".equals(iv)){
                result.setMsg("参数不合法");
                result.setSuccess(false);
                return result;
            }

            AjaxResult ajaxResult = getUserOpenId(tempId);
            if (!ajaxResult.getSuccess()) {
                result.setMsg("参数不合法");
                result.setSuccess(false);
                return result;
            }
            String sessionKey = (String) ajaxResult.getInfo();
            System.out.println("sessionKey = " + sessionKey);
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            Key sKeySpec = new SecretKeySpec(Base64.decodeBase64(sessionKey), "AES");
            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, new IvParameterSpec(Base64.decodeBase64(iv)));
            byte[] resultByte = cipher.doFinal(Base64.decodeBase64(encryptedData));
            String data = new String(PKCS7Encoder.decode(resultByte), StandardCharsets.UTF_8);
            System.out.println("=======data====== " + data);

            String openId = (String) ajaxResult.getData();
            System.out.println("openId = " + openId);
            WxUser wxUser = userService.selectByOpenId(openId);
            String mobile = wxUser.getMobile();
            if(mobile==null || "".equals(mobile)){
                System.out.println("==============data = " + data);
                JSONObject jsonObject = JSON.parseObject(data);
                String number = jsonObject.getString("phoneNumber");
                wxUser.setMobile(number).setUpdateTime(new Date());
                int i = userService.updateWxUser(wxUser);
                result.setSuccess(true);
                result.setData(number);
                result.setMsg("update success");
            }else {
                result.setSuccess(true);
                result.setData(mobile);
            }
        } catch (Exception e) {
            result.setSuccess(false);
            result.setMsg("系统打盹,请稍后...");
            e.printStackTrace();
        }
        return result;
    }
}
